package vboot.core.framework.security.authc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.stereotype.Component;
import vboot.core.common.mvc.dao.JdbcDao;
import vboot.core.framework.security.pojo.Zmenu;
import vboot.core.framework.security.pojo.Zmeta;
import vboot.core.framework.security.pojo.Zportal;

import java.util.ArrayList;
import java.util.List;

//服务于认证Service，提供门户及菜单相关逻辑处理
@Component
public class AuthcPortalHandler {

    //获取门户集合
    public List<Zportal> findPortalList(String conds) {
        String sql = "select distinct m.name,m.id,m.ornum from sys_portal_main m inner join sys_portal_role r on r.porid=m.id" +
                " inner join sys_portal_role_org ro on ro.rid=r.id where m.avtag=1 and ro.oid in (" + conds + ") order by m.ornum";
        return jdbcDao.getTp().query(sql, new BeanPropertyRowMapper<>(Zportal.class));
    }

    //获取菜单集合
    public List<Zmenu> findMenuList(String conds, List<Zportal> portalList, String porid) {
        String portals = "";
        for (Zportal zportal : portalList) {
            portals += "'" + zportal.getId() + "',";
        }
        portals = portals.substring(0, portals.length() - 1);

        //1.获取目录集合
        String direSql = "select m.porid,m.shtag,m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm from sys_portal_menu m where m.type = 'D' and m.porid in (" + portals + ") and m.avtag=1 order by m.ornum";
        List<Zmenu> direList = jdbcDao.getTp().query(direSql, (rs, rowNum) -> {
            Zmenu zmenu = new Zmenu();
            zmenu.setType("D");
            zmenu.setId(rs.getString("id"));
            zmenu.setPorid(rs.getString("porid"));
            zmenu.setPid(rs.getString("pid"));
            zmenu.setPerm(rs.getString("perm"));
            zmenu.setName(rs.getString("code"));
            zmenu.setPath(rs.getString("path"));
            zmenu.setComponent(rs.getString("comp"));
            Zmeta zmeta = new Zmeta();
            zmeta.setTitle(rs.getString("name"));
            zmeta.setOrderNo(rs.getInt("ornum"));
            zmeta.setIsHide(!rs.getBoolean("shtag"));
            if (!porid.equals(rs.getString("porid"))) {
                zmeta.setIsHide(true);
            }
            zmeta.setIcon(rs.getString("icon"));
            zmenu.setMeta(zmeta);
            return zmenu;
        });

        //2.获取菜单集合
        String sql = "select distinct m.porid,m.shtag,m.type,m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm,m.extag,m.iftag,m.catag from sys_portal_menu m inner join sys_portal_role_menu rm on rm.mid=m.id inner join sys_portal_role_org ru on ru.rid=rm.rid where m.type = 'M' and m.porid in (" + portals + ") and m.avtag=1 and ru.oid in (" + conds + ") order by m.ornum";
        List<Zmenu> list = jdbcDao.getTp().query(sql, (rs, rowNum) -> {
            Zmenu zmenu = new Zmenu();
            zmenu.setId(rs.getString("id"));
            zmenu.setType("M");
            zmenu.setPorid(rs.getString("porid"));
            zmenu.setPid(rs.getString("pid"));
            zmenu.setPerm(rs.getString("perm"));
            zmenu.setName(rs.getString("code"));
            zmenu.setPath(rs.getString("path"));
            zmenu.setComponent(rs.getString("comp"));
            Zmeta zmeta = new Zmeta();
            zmeta.setTitle(rs.getString("name"));
            zmeta.setIsHide(!rs.getBoolean("shtag"));
            if (!porid.equals(rs.getString("porid"))) {
                zmeta.setIsHide(true);
            }
            zmeta.setIsKeepAlive(rs.getBoolean("catag"));
            if(rs.getBoolean("extag")){
                zmeta.setIsLink(rs.getString("comp"));
                zmenu.setComponent("layout/routerView/link");
            }
            if(rs.getBoolean("iftag")){
                zmeta.setIsLink(rs.getString("comp"));
                zmeta.setIsIframe(true);
                zmenu.setComponent("layout/routerView/iframes");
            }
            zmeta.setOrderNo(rs.getInt("ornum"));
            zmeta.setIcon(rs.getString("icon"));
            zmenu.setMeta(zmeta);
            return zmenu;
        });

        //3.将菜单装载到目录
        List<Zmenu> shouldAddlist1 = new ArrayList<>();
        for (Zmenu zdire : direList) {
            for (Zmenu zmenu : list) {
                if (zdire.getId().equals(zmenu.getPid())) {
                    shouldAddlist1.add(zdire);
                    break;
                }
            }
        }

        List<Zmenu> shouldAddlist2 = new ArrayList<>();
        for (Zmenu zdire : direList) {
            for (Zmenu zshould : shouldAddlist1) {
                if (zshould.getPid() != null) {
                    if (zdire.getId().equals(zshould.getPid())) {
                        shouldAddlist2.add(zdire);
                        break;
                    }
                }
            }
        }

        List<Zmenu> shouldAddlist3 = new ArrayList<>();
        for (Zmenu zdire : direList) {
            for (Zmenu zshould : shouldAddlist2) {
                if (zshould.getPid() != null) {
                    if (zdire.getId().equals(zshould.getPid())) {
                        shouldAddlist3.add(zdire);
                        break;
                    }
                }
            }
        }
        list.addAll(shouldAddlist1);
        list.addAll(shouldAddlist2);
        list.addAll(shouldAddlist3);
        if (list.size() == 0) {
            return findNoPowerMenuList();
        }
        if (portalList.size() == 1) {
            return list;
        }

        //4.如果存在多个门户，则要进一步处理。
        //去除其他门户相同name或path的菜单
        List<Zmenu> backList = new ArrayList<>();
        for (Zmenu zmenu : list) {
            if (porid.equals(zmenu.getPorid())) {
                backList.add(zmenu);
            }
        }
        for (Zmenu zmenu : list) {
            if (!porid.equals(zmenu.getPorid())) {
                boolean flag = false;
                for (Zmenu backMenu : backList) {
                    if (backMenu.getName().equals(zmenu.getName()) || backMenu.getPath().equals(zmenu.getPath())) {
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    backList.add(zmenu);
                }
            }
        }
        return backList;
    }

    //获取所有门户列表，管理员用
    public List<Zportal> findAllPortalList() {
        String sql = "select id,name from sys_portal_main where avtag=1 order by ornum";
        return jdbcDao.getTp().query(sql, new BeanPropertyRowMapper<>(Zportal.class));
    }

    //获取管理员门户的菜单，管理员用
    public List<Zmenu> findSysMenuList(String porid) {
        String sql = "select m.porid,m.shtag,m.type,m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm,m.extag,m.iftag,m.catag from sys_portal_menu m where  m.avtag=1 order by m.ornum";
        List<Zmenu> list = jdbcDao.getTp().query(sql, (rs, rowNum) -> {
            Zmenu zmenu = new Zmenu();
            zmenu.setId(rs.getString("id"));
            zmenu.setPorid(rs.getString("porid"));
            zmenu.setPid(rs.getString("pid"));
            zmenu.setPerm(rs.getString("perm"));
            zmenu.setType(rs.getString("type"));
            zmenu.setName(rs.getString("code"));
            zmenu.setPath(rs.getString("path"));
            zmenu.setComponent(rs.getString("comp"));
            Zmeta zmeta = new Zmeta();
            zmeta.setIsHide(!rs.getBoolean("shtag"));
            if (!porid.equals(rs.getString("porid"))) {
                zmeta.setIsHide(true);
            }
            zmeta.setTitle(rs.getString("name"));
            zmeta.setOrderNo(rs.getInt("ornum"));
            zmeta.setIcon(rs.getString("icon"));
            zmeta.setIsKeepAlive(rs.getBoolean("catag"));
            if(rs.getBoolean("extag")){
                zmeta.setIsLink(rs.getString("comp"));
                zmenu.setComponent("layout/routerView/link");
            }
            if(rs.getBoolean("iftag")){
                zmeta.setIsLink(rs.getString("comp"));
                zmeta.setIsIframe(true);
                zmenu.setComponent("layout/routerView/iframes");
            }
            zmenu.setMeta(zmeta);
            return zmenu;
        });
        //去除其他门户相同name或path的菜单
        List<Zmenu> backList = new ArrayList<>();
        for (Zmenu zmenu : list) {
            if (porid.equals(zmenu.getPorid())) {
                backList.add(zmenu);
            }
        }
        for (Zmenu zmenu : list) {
            if (!porid.equals(zmenu.getPorid())) {
                boolean flag = false;
                for (Zmenu backMenu : backList) {
                    if (backMenu.getName().equals(zmenu.getName()) || backMenu.getPath().equals(zmenu.getPath())) {
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    backList.add(zmenu);
                }
            }
        }
        return backList;
    }

    //如果用户没有菜单授权，则返回一个未授权的菜单
    public List<Zmenu> findNoPowerMenuList() {
        List<Zmenu> list = new ArrayList<>();
        Zmenu zmenu = new Zmenu();
        zmenu.setType("M");
        zmenu.setId("Home");
        zmenu.setName("Home");
        zmenu.setPath("/home");
        zmenu.setComponent("/home/noPower");
        Zmeta zmeta = new Zmeta();
        zmeta.setTitle("未授权");
        zmeta.setOrderNo(0);
        zmeta.setIsHide(false);
        zmeta.setIcon("ele-Lock");
        zmenu.setMeta(zmeta);
        list.add(zmenu);
        return list;
    }

    //使用递归方法建树
    public List<Zmenu> buildByRecursive(List<Zmenu> nodes)
    {
        List<Zmenu> list = new ArrayList<>();
        for (Zmenu node : nodes) {
            if (node.getPid() == null)
            {
                list.add(findChildrenByTier(node, nodes));
            }
            else
            {
                boolean flag = false;
                for (Zmenu node2 : nodes) {
                    if (node.getPid().equals(node2.getId()))
                    {
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    list.add(findChildrenByTier(node, nodes));
                }
            }
        }
        return list;
    }

    //递归查找子节点
    private Zmenu findChildrenByTier(Zmenu node, List<Zmenu> nodes)
    {
        for (Zmenu item : nodes) {
            if (node.getId().equals(item.getPid()))
            {
                if (node.getChildren() == null)
                {
                    node.setChildren(new ArrayList<>());
                }
                node.getChildren().add(findChildrenByTier(item, nodes));
            }
        }
        return node;
    }

    @Autowired
    private JdbcDao jdbcDao;

}
